
//---------------------------------------------------------------------------------------------------
template <class Real>
Vector2<Real>::Vector2()
{
}
//---------------------------------------------------------------------------------------------------
template <class Real>
Vector2<Real>::Vector2(Real fX, Real fY)
{
	m_afTuple[0] = fX;
	m_afTuple[1] = fY;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
Vector2<Real>::Vector2(const Real* afTuple)
{
	m_afTuple[0] = afTuple[0];
	m_afTuple[1] = afTuple[1];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
Vector2<Real>::Vector2(const Vector2& rkV)
{
	m_afTuple[0] = rkV.X();
	m_afTuple[1] = rkV.Y();
}
//---------------------------------------------------------------------------------------------------
template <class Real>
int Vector2<Real>::CompareArrays(const Vector2& rkV) const
{
	return memcmp(m_afTuple, rkV.m_afTuple, 2 * sizeof(Real));
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator== (const Vector2& rkV) const
{
	return CompareArrays(rkV) == 0;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator!= (const Vector2& rkV) const
{
	return CompareArrays(rkV) != 0;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator< (const Vector2& rkV) const
{
	return CompareArrays(rkV) < 0;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator<= (const Vector2& rkV) const
{
	return CompareArrays(rkV) <= 0;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator> (const Vector2& rkV) const
{
	return CompareArrays(rkV) > 0;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
bool Vector2<Real>::operator>= (const Vector2& rkV) const
{
	return CompareArrays(rkV) >= 0;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>::operator Real* ()
{
	return m_afTuple;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>::operator const Real* () const
{
	return m_afTuple;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::operator[] (int i) const
{
	assert( i == 0 || i == 1);
	return m_afTuple[i];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real& Vector2<Real>::operator[] (int i)
{
	assert( i == 0 || i == 1);
	return m_afTuple[i];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::X() const
{
	return m_afTuple[0];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real& Vector2<Real>::X()
{
	return m_afTuple[0];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::Y() const
{
	return m_afTuple[1];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real& Vector2<Real>::Y()
{
	return m_afTuple[1];
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>& Vector2<Real>::operator= (const Vector2& rkV)
{
	m_afTuple[0] = rkV.m_afTuple[0];
	m_afTuple[1] = rkV.m_afTuple[1];
	return *this;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> Vector2<Real>::operator+ (const Vector2& rkV) const
{
	return Vector2(
		m_afTuple[0] + rkV.m_afTuple[0],
		m_afTuple[1] + rkV.m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> Vector2<Real>::operator- (const Vector2& rkV) const
{
	return Vector2(
		m_afTuple[0] - rkV.m_afTuple[0],
		m_afTuple[1] - rkV.m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> Vector2<Real>::operator* (const Real fScalar) const
{
	return Vector2(
		m_afTuple[0] * fScalar,
		m_afTuple[1] * fScalar);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> operator* (Real fScalar, const Vector2<Real>& rkV)
{
	return Vector2(
		fScalar * rkV[0],
		fScalar * rkV[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> Vector2<Real>::operator/ (const Real fScalar) const
{
	Vector2 kOut;
	if (fScalar != 0.0f)
	{
		Real fInv = 1.0f / fScalar;
		kOut.m_afTuple[0] = m_afTuple[0] * fInv;
		kOut.m_afTuple[1] = m_afTuple[1] * fInv;
	}
	else
	{
		kOut.m_afTuple[0] = FLT_MAX;
		kOut.m_afTuple[1] = FLT_MAX;
	}
	return kOut;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real> Vector2<Real>::operator- () const
{
	return Vector2(
		-m_afTuple[0],
		-m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>& Vector2<Real>::operator += (const Vector2& rkV)
{
	m_afTuple[0] += rkV.m_afTuple[0];
	m_afTuple[1] += rkV.m_afTuple[1];
	return *this;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>& Vector2<Real>::operator -= (const Vector2& rkV)
{
	m_afTuple[0] -= rkV.m_afTuple[0];
	m_afTuple[1] -= rkV.m_afTuple[1];
	return *this;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>& Vector2<Real>::operator *= (Real fScalar)
{
	m_afTuple[0] *= fScalar;
	m_afTuple[1] *= fScalar;
	return *this;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Vector2<Real>& Vector2<Real>::operator /= (Real fScalar)
{
	if (fScalar != 0.0f)
	{
		Real fInv = 1.0f / fScalar;
		m_afTuple[0] *= fInv;
		m_afTuple[1] *= fInv;
	}
	else
	{
		m_afTuple[0] = FLT_MAX;
		m_afTuple[1] = FLT_MAX;
	}
	return *this;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::Length() const
{
	return sqrt(
		m_afTuple[0]*m_afTuple[0] +
		m_afTuple[1]*m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::SquaredLength() const
{
	return (		
		m_afTuple[0]*m_afTuple[0] +
		m_afTuple[1]*m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::Dot(const Vector2& rkV) const
{
	return (
		m_afTuple[0]*rkV.m_afTuple[0] +
		m_afTuple[1]*rkV.m_afTuple[1]);
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline Real Vector2<Real>::Normalize()
{
	Real fLength = Length();
	if (fLength > 1e-06f)
	{
		Real fInv = 1.0f / fLength;
		m_afTuple[0] *= fInv;
		m_afTuple[1] *= fInv;
	}
	else
	{
		fLength = 0.0f;
		m_afTuple[0] = 0.0f;
		m_afTuple[1] = 0.0f;
	}

	return fLength;
}
//---------------------------------------------------------------------------------------------------
template <class Real>
inline bool Vector2<Real>::SameAs(const Vector2& rkV) const
{
	Real e = (Real)0.0001;
	if ((Real)fabs(m_afTuple[0] - rkV.X()) < e
		&& (Real)fabs(m_afTuple[1] - rkV.Y()) < e)
	{
		return true;
	}
	return false;
}
//---------------------------------------------------------------------------------------------------